package com.chub.study.modules.controller;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.incrementer.DefaultIdentifierGenerator;
import com.baomidou.mybatisplus.core.incrementer.IdentifierGenerator;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.chub.RespResult;
import com.chub.study.modules.dto.DateReq;
import com.chub.study.modules.dto.DateResp;
import com.chub.study.modules.entity.TCity;
import com.chub.study.modules.mapper.TCityMapper;
import com.chub.study.modules.service.TCityService;
import com.chub.study.util.SmartWrapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;


import javax.annotation.Resource;
import javax.validation.Valid;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 行政区划表 前端控制器
 * </p>
 *
 * @author chub
 * @since 2021-08-26
 */
//@RunWith(SpringRunner.class)
@Api(tags = "地区信息的服务")
@RestController
@RequestMapping("/modules")
public class TCityController extends BaseController {

//    @Resource
    @Autowired(required = false)
    private TCityMapper cityMapper;

//    @Autowired(required = false)
    @Resource
    private TCityService cityService;



    @ApiOperation(value = "根据父行政区ID，获取所属的行政区的信息。")
    @GetMapping("/getXingzhengqu")
    public List<TCity> getXingzhengqu(@ApiParam("父行政区编号") @RequestParam(name="cityId") String id) {
        //  访问地址   http://localhost:7788/modules/getXingzhengqu?cityId=371700
        logger.info("要查询的行政区号 = {}", id);
        QueryWrapper<TCity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("PARENT_ID", id).or().eq("CITY_ID", id);

        logger.info("查询行政区信息，其中父行政区号为 = {}", id);
        List<TCity> list2 = cityService.queryCityByParentId(id);

        logger.info("根据多个条件查询行政区信息，其中行政区号或父行政区号为 = {}", id);
        Map<String, Object> map = new HashMap<>();
        map.put("CITY_ID", id);
        List<TCity> list3 = cityService.queryCityList(map);

        List<TCity> list = cityMapper.selectList(queryWrapper);


        //String
        List<TCity> list1  = cityService.queryCityInfo(id);
        logger.info("参数是String,值为 = {}， 返回数据是List<TCity>，值为--> {}", id, list1);

       // Map<String, Object> forQuery = new HashMap();
       // forQuery.put("CITY_NAME", "曹县");
       // forQuery.put("CITY_ID", 371721);
       // //Map
       // List<TCity> list2  = cityService.queryCityInfoByMap(forQuery);
       // logger.info("参数是Map,值为 = {}", forQuery);
//
//
//        TCity city = new TCity();
//        city.setCityName("菏泽");
//
//        //Bean
//        List<TCity> list3  = cityService.queryCityInfoByBean(city);
//        logger.info("参数是Bean,值为 = {}", city);
//
//        //返回值是 Map<String, Object>
//        List<Map<String, Object>> list4  = cityService.queryCityInfoRespMap(id);
//        logger.info("参数是String,值为 = {}， 返回数据是List<Map>，值为--> {}", id, list4);
//
//        //返回值是 Arrays ， list里的值全部是null
//        List<Arrays> list5  = cityService.queryCityInfoRespArray(id);
//        logger.info("参数是String,值为 = {}， 返回数据是List<Arrays>，值为--> {}", id, list5);
//
//
//        //返回值是 Arrays
//        List<String> list6  = cityMapper.queryCityInfoRespArrString(id);
//        logger.info("参数是String,值为 = {}， 返回数据是List<String>，值为--> {}", id, list6);
//
//        //返回值是 Map<String, TCity>
//        Map<Integer, TCity> map7  = cityMapper.queryCityInfoAsMap(id);
//        logger.info("参数是String,值为 = {}， 返回数据是Map<String, TCity>，值为--> {}", id, map7);
//
//
//        //String
//        List<TCity> list7  = cityMapper.queryCityInfoList(id);
//        logger.info("参数是String,值为 = {}， 返回数据是List<TCity>，值为--> {}", id, list7);

        return list;

        // List<TCity> cityList = new ArrayList<>();
        // TCity city1 = new TCity();
        // city1.setCityId(371702);
        // city1.setCityLvl(153003);
        // city1.setCityName("牡丹区");
        // cityList.add(city1);
        //
        // TCity city2 = new TCity();
        // city1.setCityId(371702);
        // city1.setCityLvl(153003);
        // city1.setCityName("牡丹区");
        // cityList.add(city2);
        //
        // return cityList;
    }

    @ApiOperation(value = "根据行政区Map，获取所属的行政区的信息。")
    @PostMapping("/getXingzhengquByMap")
    public List<TCity> getXingzhengquByMap(@ApiParam("行政区Map") @RequestBody Map<String,String> forQuery) {
        //  访问地址   http://localhost:7788/modules/getXingzhengquByMap
        // {
        //     "371703": "定陶区",
        //         "371721": "曹县"
        // }

        logger.info("要查询的行政区Map = {}", forQuery);

        // Map<String, String> forQuery = new HashMap<>();
        // // CITY_ID   CITY_NAME
        // forQuery.put("371721", "曹县");
        // forQuery.put("371703", "定陶区");

        List<TCity> list2  = cityService.queryCityInfoByMapKeyValue(forQuery);
        logger.info("参数是Map = {}, 查询结果 = {}", forQuery, list2);

        List<TCity> list3  = cityService.queryCityInfoByMapKey(forQuery);
        logger.info("参数是Map = {}, 查询结果 = {}", forQuery, list3);

        List<TCity> list4  = cityService.queryCityInfoByMapValue(forQuery);
        logger.info("参数是Map = {}, 查询结果 = {}", forQuery, list4);

        return list2;


    }


    @ApiOperation(value = "根据Bean，获取城市列表。")
    @PostMapping("/queryCityListByBean")
    public RespResult<List<TCity>> queryCityListByBean(@ApiParam("城市Bean") @RequestBody TCity city) {
        logger.info("要查询的行政区 = {}", city);
        List<TCity> list  = cityService.queryCityListByBean(city);
        logger.info("返回数据是List<TCity>，值为--> {}",  list);
        // return list;
        return RespResult.success("根据Bean，获取城市列表", list);

    }

    @ApiOperation(value = "根据Map，获取城市列表。")
    @PostMapping("/queryCityListByMap")
    public RespResult<List<TCity>> queryCityListByMap(@ApiParam("城市Bean") @RequestBody Map<String, Object> map) {
        logger.info("要查询的行政区 = {}", map);
        List<TCity> list  = cityService.queryCityListByMap(map);
        logger.info("返回数据是List<TCity>，值为--> {}",  list);
        return RespResult.success("根据Map，获取城市列表", list);
    }

    @ApiOperation(value = "根据Map，获取城市列表。")
    @PostMapping("/queryCityListByMapRespBeanList")
    public RespResult<List<TCity>> queryCityListByMapRespBeanList(@ApiParam("城市Bean") @RequestBody Map<String, Object> map) {
        logger.info("要查询的行政区 = {}", map);
        List<TCity> list  = cityService.queryCityListByMap(map);
        logger.info("返回数据是List<TCity>，值为--> {}",  list);
        return RespResult.success("根据Map，获取城市列表", list);
    }

    @ApiOperation(value = "根据Id，获取城市列表，返回数据是List<Map>。")
    @PostMapping("/queryCityInfoRespMap")
    public Map<Integer, TCity> queryCityInfoRespMap(@ApiParam("父行政区号") String id) {
        logger.info("父行政区号 = {}", id);
        Map<Integer, TCity> list4  = cityService.queryCityInfoRespMap(id);
        logger.info("参数是父行政区号,值为 = {}， 返回数据是List<Map<String, TCity>>，值为--> {}", id, list4);
        return list4;
    }

    @ApiOperation(value = "根据Id，获取城市列表，返回数据是List<Map>。")
    @PostMapping("/queryCityInfoRespMap1")
    public List<Map<String, Object>> queryCityInfoRespMap1(@ApiParam("父行政区号")  String id) {
        logger.info("父行政区号 = {}", id);
        List<Map<String, Object>> list4  = cityService.queryCityInfoRespMap1(id);
        logger.info("参数是父行政区号,值为 = {}， 返回数据是List<Map<String, TCity>>，值为--> {}", id, list4);
        return list4;
    }

    @ApiOperation(value = "根据Id，获取城市列表，返回数据是Arrays。不能正常返回！")
    @PostMapping("/queryCityInfoRespArray")
    public List<Arrays> queryCityInfoRespArray(@ApiParam("城市id") String id) {
        logger.info("要查询的行政区 = {}", id);
        List<Arrays> list4  = cityService.queryCityInfoRespArray(id);
        logger.info("参数是String,值为 = {}， 返回数据是Arrays，值为--> {}", id, list4);
        return list4;
    }

    @ApiOperation(value = "根据Id，获取城市列表，返回数据是List<String>。")
    @PostMapping("/queryCityInfoRespArrString")
    public List<String> queryCityInfoRespArrString(@ApiParam("城市id") String id) {
        logger.info("要查询的行政区 = {}", id);
        //        //返回值是 Map<String, Object>
        List<String> list4  = cityService.queryCityInfoRespArrString(id);
        logger.info("参数是String,值为 = {}， 返回数据是List<String>，值为--> {}", id, list4);
        return list4;
    }


    @ApiOperation(value = "根据Id，获取城市列表，返回数据是List<String>。")
    @PostMapping("/queryCityInfoAsMap")
    public Map<Integer, TCity> queryCityInfoAsMap(@ApiParam("父行政区号") String id) {
        logger.info("父行政区号 = {}", id);
        //        //返回值是 Map<String, Object>
        Map<Integer, TCity> list4  = cityService.queryCityInfoAsMap(id);
        logger.info("参数是父行政区号,值为 = {}， 返回数据是Map<Integer, TCity>，值为--> {}", id, list4);
        return list4;
    }

    @ApiOperation(value = "根据List<Id>，获取城市列表，返回数据是List<TCity>。")
    @PostMapping("/queryCityInfoByList")
    public List<TCity> queryCityInfoByList(@ApiParam("行政区号") @RequestBody List<String> list) {
//  一定要加 @RequestBody 否则报错：No primary or single unique constructor found for interface java.util.Lis
//  postman 传输的参数   ["371703", "371702"]
        logger.info("行政区号 = {}", list);
        List<TCity> list4  = cityService.queryCityInfoByList(list);
        logger.info("参数是行政区号,值为 = {}， 返回数据是List<TCity>，值为--> {}", list, list4);
        return list4;
    }

    @ApiOperation(value = "根据Id，获取城市列表，返回数据是List<TCity>。")
    @PostMapping("/queryCityInfoByArray")
    public List<TCity> queryCityInfoByArray(@ApiParam("行政区号") @RequestBody String[] cityIds) {
//  一定要加 @RequestBody 否则报错：The expression 'array' evaluated to a null value.
//  postman 传输的参数   ["371703", "371702"]
        logger.info("行政区号 = {}", (Object) cityIds);
        List<TCity> list4  = cityService.queryCityInfoByArray(cityIds);
        logger.info("参数是行政区号,值为 = {}， 返回数据是List<TCity>，值为--> {}", cityIds, list4);
        return list4;
    }

    @ApiOperation("创建")
    @PostMapping("/create")
    public RespResult<String> create(@Valid @RequestBody TCity tCity) {

        logger.info("请求参数--->{}", tCity);

        IdentifierGenerator idUtil = new DefaultIdentifierGenerator();



        cityService.save(tCity);
        return RespResult.success();
    }

    @ApiOperation("创建")
    @PostMapping("/createByJsonString")
    public RespResult<String> createByJsonString(@Valid @RequestBody String json) {
        TCity tCity = JSONObject.parseObject(json, TCity.class);
        cityService.save(tCity);
        return RespResult.success();
    }

    @ApiOperation(value = "删除")
    @PostMapping("/delete")
    public RespResult<String> delete(@RequestParam String id) {
        cityService.removeById(id);
        return RespResult.success();
    }

    @Transactional(rollbackFor = Exception.class)
    @ApiOperation(value = "修改")
    @PostMapping("/modify")
    public RespResult<String> modify(@Valid @RequestBody TCity tCity) {
        logger.info("请求参数--->{}", tCity);
        Long id = tCity.getId();
        // TCity oldCity = cityService.getById(tCity);
        TCity oldCity = cityMapper.selectById(tCity.getId());

        logger.info("备份修改前的行政区信息--->{}", oldCity);
        oldCity.setId(null);
        oldCity.setDelFlag(1);
        cityMapper.insert(oldCity);


        String oldName = oldCity.getCityName();
        String newName = tCity.getCityName();
        oldCity.setCityName(newName);
//        oldCity.setUptTime(LocalDateTime.now());
//        cityService.updateById(oldCity);
        logger.info("修改后的行政区信息--->{}", tCity);
        // tCity.setId(oldCity.getId());
        cityService.updateById(tCity);
        cityService.saveOrUpdate(tCity);

        return RespResult.success("行政区主键-->{}, 城市-->{}, 更名为-->{}", id, oldName, newName);
    }

    @ApiOperation(value = "修改")
    @PostMapping("/modifyByJsonString")
    public RespResult<String> modifyByJsonString(@Valid @RequestBody String json) {
        logger.info("请求参数--->{}", json);
        TCity tCity = JSONObject.parseObject(json, TCity.class);
        Long id = tCity.getId();
        TCity oldCity = cityService.getById(tCity);
        logger.info("修改前的行政区信息--->{}", oldCity);
        String oldName = oldCity.getCityName();

        String newName = tCity.getCityName();
        oldCity.setCityName(newName);
//        oldCity.setUptTime(LocalDateTime.now());
//        cityService.updateById(oldCity);
        logger.info("修改后的行政区信息--->{}", tCity);
        tCity.setId(oldCity.getId());
        cityService.updateById(tCity);

        return RespResult.success("行政区主键-->{}, 城市-->{}, 更名为-->{}", id, oldName, newName);
    }

    @ApiOperation(value = "查询详情")
    @GetMapping("/detail")
    public RespResult<TCity> detail(@RequestParam String id) {
        return RespResult.success(cityService.getById(id));
    }

    @ApiOperation(value = "分页查询")
    @PostMapping("/queryByPage")
    public RespResult<IPage<TCity>> queryByPage(@RequestBody JSONObject queryObject) {


        Wrapper<TCity> queryWrapper1 = new QueryWrapper();


        SmartWrapper<TCity> smartWrapper = new SmartWrapper<>();
        smartWrapper.parse(queryObject, TCity.class);

        QueryWrapper<TCity> queryWrapper = smartWrapper.getQueryWrapper();
        // WHERE (PARENT_ID = ? AND (CITY_NAME = ? OR CITY_NAME = ?))
        queryWrapper.eq("PARENT_ID", 371700);
        queryWrapper.and(wrapper->wrapper.eq("CITY_NAME", "郓城县").or().eq("CITY_NAME", "曹县"));

        IPage<TCity> page = smartWrapper.generatePage();
        cityService.page(page, queryWrapper);
        return RespResult.success(page);
    }

    @ApiOperation(value = "分页查询")
    @PostMapping("/queryByPage1")
    public RespResult<IPage<Map<String, Object>>> queryByPage1(@RequestBody JSONObject queryObject) {
        int pageNum = 1, pageSize = 10;
        if (ObjectUtil.isNotEmpty(queryObject.get("pageNum"))) {
            pageNum = Integer.parseInt(queryObject.get("pageNum").toString()) ;
        }
        if (ObjectUtil.isNotEmpty(queryObject.get("pageSize"))) {
            pageSize = Integer.parseInt(queryObject.get("pageSize").toString()) ;
        }
        /* 设置页大小，当前页，总量，isSearchCount */
        // IPage<Map<String, Object>> page1 = new Page<>(pageNum, pageSize, 100 , false);

        IPage<Map<String, Object>> page = new Page<>(pageNum, pageSize);

        Map<String, Object> forQuery = new HashMap<>();
        forQuery.put("parentId", 371700);
        // forQuery.put("cityName", "郓城县");
        //这里用自定义的SQL来实现分页查询，可以实现多表关联查询。
        IPage<Map<String, Object>> respPage = cityService.queryByPage1(page, forQuery);
        return RespResult.success(page);
    }

    @ApiOperation(value = "根据时间，获取城市列表，返回数据是List<TCity>。")
    @PostMapping("/queryCityInfoByUptTime")
    public List<TCity> queryCityInfoByUptTime(@ApiParam("更新时间") @RequestBody TCity tCity) {
        logger.info("更新时间 = {}", tCity.getUptTime());
        List<TCity> list4  = cityService.queryCityInfoByUptTime(tCity);
        logger.info("返回数据是List<TCity>，值为--> {}", list4);
        return list4;
    }


    @RequestMapping("/hello")
    public String index() {
        return "Hello World";
    }


    @ApiOperation(value = "事务处理")
    @PostMapping("/transactionHandle")
    @Transactional
    public RespResult transactionHandle(String cityId){
        QueryWrapper<TCity> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("CITY_ID", cityId);
        TCity city = cityService.getOne(queryWrapper);

        city.setDelFlag(1);
        city.setUptTime(LocalDateTime.now());
        cityService.updateById(city);

        city.setId(null);
        city.setCityName("又一个县");
        city.setDelFlag(0);
        city.setCrtUser("admin123");
        city.setCrtTime(LocalDateTime.now());
        city.setUptTime(LocalDateTime.now());
        cityService.saveOrUpdate(city);

        return RespResult.success();
    }

    // @RequestParam -->  http://localhost:7788/modules/queryByParentIdReturnListBean?parentId=371700
    // @RequestBody  -->

    @ApiOperation(value = "根据父地区号，获取城市列表，返回数据是List<TCity>。")
    @PostMapping("/queryByParentIdReturnListBean")
    public List<TCity> queryByParentIdReturnListBean(@ApiParam("父地区号")  @RequestBody Map<String, Object> forQuery) {

        List<TCity> list4  = cityMapper.queryByParentIdReturnListBean(forQuery);

        return list4;
    }

    @ApiOperation(value = "根据父地区号，获取城市列表，返回数据是List<Map>。")
    @PostMapping("/queryByParentIdReturnListMap")
    public List<TCity> queryByParentIdReturnListMap(@ApiParam("父地区号")  @RequestBody Map<String, Object> forQuery) {

        List<TCity> list4  = cityMapper.queryByParentIdReturnListMap(forQuery);

        return list4;
    }


    @ApiOperation(value = "新建城市信息，并返回主键。")
    @PostMapping("/insertAndReturnPk")
    public void insertAndReturnPk(@ApiParam("城市信息")  @RequestBody TCity tCity) {

        int count = cityMapper.insertAndReturnPk(tCity);
        logger.info("cityPK: {}", tCity.getId());
        // return cityPK;
    }

    @ApiOperation(value = "测试日期时间")
    @PostMapping("/testDate")
    public RespResult testDate(@ApiParam("测试日期时间")  @RequestBody DateReq req) {

        logger.info("接收传入的时间参数测试。");
        logger.info("传入的时间参数：{}", JSONObject.toJSONString(req));

        DateResp resp = new DateResp();
        BeanUtil.copyProperties(req, resp);


        return RespResult.success(resp);




    }





}

